var dataSync = {
    
    db: false,
    tables: [],
    schema: false,
    
    loadSchema: function(s){
        this.schema = s;
        
        for (var tableName in s.tables) if (s.tables.hasOwnProperty(tableName)){
            var columnsArray = [],
                t=s.tables[tableName],
                columns=t.columns;
            
            for (var columnName in columns)
            if (columns.hasOwnProperty(columnName) && (typeof columns[columnName]=='string')){
                columnsArray.push(
                    columnsArray[columnName] = {name: columnName, type: columns[columnName]}
                )
            }
            
            this.tables.push(
                this.tables[tableName] = {name: tableName, label: t.label, columns: columnsArray, fks: []}
            )
        }
        
        Ext.each(this.tables, function(t,idx,tables){
            t.deps = [];
            Ext.each(t.columns, function(c,idx,columns){
                var parent = tables[c.name[0].toUpperCase() + c.name.substring(1)];
                if (parent){
                    t.fks.push(t.fks[c] = {"parent": parent, column: c})
                    Ext.apply(c, {"fk": t.fks[c]})
                }
            })
        })
        
        Ext.each(this.tables, function(t,idx,tables){
            Ext.each(t.fks, function(fk){
                fk.parent.deps.push({ child: t, "fk": fk, name: 'to'+t.name+'s'})
            })
        })
        
    },
        
    credentials: {
        login: '',
        pwd: '',
        view: ''
    },
    
    downloadSession:{},
    
    serverSession: {
        logRequest: function() {}
    },
    
    setCredentials: function (r) {
        dataSync.credentials.login=r.get('login');
        dataSync.credentials.pwd=r.get('password');
        dataSync.reconnect();
    },
    
    reconnect: function() {
        if (typeof dataSync.serverSession.id == 'string')
            dataSync.serverLogoff(dataSync.serverLogin)
        else
            dataSync.serverLogin()   
    },
    
    serverLogin: function() {
        dataSync.ajax.request({
            label: 'Login',
            params: { command: 'authenticate', username: dataSync.credentials.login, password: dataSync.credentials.pwd },
            
            success: dataSync.requestOpenView,
            scope:dataSync,
            
            failure: function(response, opts) {
                console.log('server login request failure');
                console.log(response);
                console.log(opts);
            }
        })
    },

    serverLogoff: function(cb) {
        dataSync.ajax.request({
            label: 'Logoff',
            method: 'GET',
            params: { command: 'logoff' },
            scope: dataSync,
            afterSuccess: cb,
            
            success: function(response, opts) {
                console.log('server logoff request: success');
                var node = Ext.DomQuery.selectNode('session', response.responseXML);
                if (node) {
                    dataSync.serverSession.id=null;
                }
                
                if (opts.afterSuccess) opts.afterSuccess.call(this)
            },
            
            failure: function(response, opts) {
                console.log('server login request failure');
                console.log(response);
            }
        })
    },

    requestOpenView: function(response) {
        var node = Ext.DomQuery.selectNode('session', response.responseXML);
        
        if (node && node.hasAttribute('id'))
            dataSync.serverSession.id = String(node.getAttribute('id'))
        else {
            console.log ('Invalid credentials');
            return
        }
        ;
        
        console.log ('View open request');
        
        dataSync.ajax.request({
            label: 'Open view',
            params: { views: dataSync.credentials.view},
            scope: dataSync,
            success: function(response, opts) {
                console.log ('View open response');
                var node = Ext.DomQuery.selectNode('sysuser', response.responseXML);
                if (node) dataSync.serverSession.viewOpen = true;
                else {
                    dataSync.serverSession.viewOpen = false;
                }
                console.log ('dataSync.serverSession.viewOpen:', dataSync.serverSession.viewOpen);
            },
            failure: function(response, opts) {
                console.log('Open view request failure');
                console.log(response);
                console.log(opts);
            }
        })
    },

    
    requestDownload: function(offset) {
        dataSync.downloadSession = {
            id: Ext.id()
        };
        dataSync.ajax.request({
            label: 'Data get',
            params: { "offset": offset, pipeline: 'download'},
            scope:dataSync,
           
            success: dataSync.processDowloadData,
            failure: function(response, opts) {
                console.log('Download request failure');
                console.log(response);
                console.log(opts);
            }
        })
        
        console.log('Download request sent');
    },
    
    processDowloadData: function(response, opts) {
        
        console.log('Download request response size: '+response.responseText.length);
        
        for (var tableName in dbSchema.tables) if (dbSchema.tables.hasOwnProperty(tableName)) 
            dataSync.persistTableData (tableName, response.responseXML)
        
    },
    
    persistTableData: function(tableName, rowsetXML) {
        var 
            downloadData=Ext.DomQuery.select(tableName, rowsetXML),
            table = dbSchema.tables[tableName]
        
        if (!table || downloadData.length<=0) return;        
        
        dataSync.db.transaction(
            function(t){
                var rowsProcessed = 0;
                
                for (var i=0; i<downloadData.length; i++){
                    var columns = table.columns, columnsList='', qList='', dataArray=[];
                    
                    if (!downloadData[i].hasAttributes()) continue;
                    
                    for (var columnName in columns) if (columns.hasOwnProperty(columnName) && (typeof columns[columnName]=='string')) {
                        columnsList += columnName + ', ';
                        qList += '?,';
                        var datum = downloadData[i].getAttribute(columnName);
                        
                        if (!datum) {
                            var parent=downloadData[i].parentNode;
                            
                            if (parent.tagName.toLowerCase()==columnName)
                                datum=parent.getAttribute('id');
                        }
                        
                        dataArray.push(datum);
                    }
                    
                    columnsList=columnsList.slice(0, columnsList.length - 2);
                    qList=qList.slice(0, qList.length - 1);
                    
                    var sqlStatement='replace into '+tableName+'('+columnsList+') values ('+qList+')';
                    
                    t.executeSql(sqlStatement, dataArray, nullDataHandler, errorHandler);
                    rowsProcessed++;
                }
                console.log('Processed table: '+tableName+', rows: '+rowsProcessed);
            }
        )
        
        var firstDataChildren=downloadData[0].childNodes;
        
        for (var ei=0; ei<firstDataChildren.length; ei++){
            var elem=firstDataChildren[ei];
            switch (elem.tagName) {
                case 'choise':
                    var totalPos=parseInt(elem.getAttribute('options-count')),
                        currentPos=parseInt(elem.getAttribute('current-position'));
                    dataSync.requestChoise(tableName, currentPos, totalPos);
            }
        }
    },

    requestChoise: function(tableName, currentPos, totalPos) {
        var params = {"filter": tableName, pipeline: 'download'};
        
        params[tableName]='next';
        if (!currentPos) currentPos=0;
        
        dataSync.ajax.request({
            label: tableName+' '+currentPos.toString()+'/'+totalPos.toString(),
            "params": params,
            timeout: 120000,
            
            success: dataSync.processDowloadData,
            failure: function(response, opts) {
                console.log('Choise request failure');
                console.log(response);
                console.log(opts);
            }
        })
     
        console.log('Table: '+tableName+' choice request '+currentPos.toString()+' of '+totalPos.toString());
    }

}